//
//  BBPack.m
//  BBGameLib
//
//  Created by Eric on 12/23/11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "BBPackAction.h"




@implementation BBPackAction
@synthesize node=_node, action=_action;
@synthesize delegate=_delegate,callback=_callback, data=_data;

-(void)dealloc{
    //NSLog(@"BBPackAction:dealloc");
    self.node = nil;
    self.action = nil;
    self.delegate = nil;
    self.data = nil;
    [super dealloc];
}


+(id)action:(CCNode*)node ccaction:(CCFiniteTimeAction*)action{
    BBPackAction* pack = [[[[self class] alloc] init] autorelease];
    [pack initPack:node ccaction:action];
    return pack;
}
-(void)initPack:(CCNode*)node ccaction:(CCFiniteTimeAction*)action{
    self.node = node;
    self.action = action;
    //[_action retain];
}

-(void)callbackMethod{
    if (_delegate) {
        [_delegate performSelector:_callback withObject:self withObject:_data];
    }  
    self.delegate = nil;
    self.data = nil;
}

-(void)doAction{
    //NSAssert(_node.parent!=nil, @"_node.parent!=nil");
    if (_action&&_node&&[_node isRunning]) {
        id func = [CCCallFunc actionWithTarget:self selector:@selector(callbackMethod)];
        id seq = [CCSequence actions:_action, func, nil];
        [_node runAction:seq];
    }else{
        [self callbackMethod];
    }
    
}
@end



@implementation BBPackActionAsyn

-(void)doAction{
    [_node runAction:_action];
    [self callbackMethod];
    
}

@end


@implementation BBPackSequence
-(void)dealloc{
    // NSLog(@"BBPackSequence:dealloc:%@", self);
    [_packs release];
    [super dealloc];
}

+(id)actions:(BBPackAction*)pack1,...{
    id seq = [[[[self class] alloc] init] autorelease];
    va_list params;
	va_start(params,pack1);
	
	BBPackAction *now = pack1;
	while( now ) {
        [seq addPack:now];
		now = va_arg(params,BBPackAction*);
	}
	va_end(params);
	return seq;
}

+(id) actionsWithArray: (NSArray*) actions
{
    id seq = [[[[self class] alloc] init] autorelease];
	[seq addPacks:actions];
	return seq;
}
+(id) actions
{
    id seq = [[[[self class] alloc] init] autorelease];
	return seq;
}
-(id)init{
    if (self = [super init]) {
        _packs = [[NSMutableArray alloc] init];
    }
    return self;
}
-(void)doAction{
    if ([_packs count]>0) {
        BBPackAction* pack = [_packs objectAtIndex:0];
        [pack retain];
        [_packs removeObjectAtIndex:0];
        [pack doAction];
        [pack release];
    }else{
        if (self.delegate) {
            [self.delegate performSelector:_callback withObject:self withObject:self.data];
        }  
    }
}
-(void)addPack:(BBPackAction*)pack{
    pack.delegate = self;
    pack.callback = @selector(packFinished:data:);
    pack.data = nil;
    [_packs addObject:pack];
    
}
-(void)addPacks:(NSArray*)packs{
    for (BBPackAction* pack in packs) {
        [self addPack:pack];
    }
}
-(void)packFinished:(BBPackAction*)pack data:(id)data{
    [self doAction];
}
@end


@implementation BBPackSequenceAsyn
-(id)init{
    if (self=[super init]) {
        callbackDone = NO;
    }
    return self;
}
-(void)doAction{
    if (!callbackDone) {
        callbackDone = YES;
        if (self.delegate) {
            [self.delegate performSelector:_callback withObject:self withObject:self.data];
        }
    }
    if ([_packs count]>0) {
        BBPackAction* pack = [_packs objectAtIndex:0];
        [pack retain];
        [_packs removeObjectAtIndex:0];
        [pack doAction];
        [pack release];
    }
   
}
@end








@implementation BBPackSpawn
-(void)doAction{
    if ([_packs count]>0) {
        NSMutableArray* packs_tmp = [NSMutableArray arrayWithArray:_packs];
        for (BBPackAction* pack in packs_tmp) {
            [pack doAction];
        }
    }else{
        [self.delegate performSelector:_callback withObject:self withObject:self.data];
    }
}

-(void)packFinished:(BBPackAction*)pack data:(id)data{
    [_packs removeObject:pack];
    if ([_packs count]==0) {
        [self.delegate performSelector:_callback withObject:self withObject:self.data];
    }
}
@end


@implementation BBPackSpawnAsyn
-(id)init{
    if (self=[super init]) {
        callbackDone = NO;
    }
    return self;
}
-(void)doAction{
    if (!callbackDone) {
        callbackDone = YES;
        if (self.delegate) {
            [self.delegate performSelector:_callback withObject:self withObject:self.data];
        }
    }
    [super doAction];
    
}

-(void)packFinished:(BBPackAction*)pack data:(id)data{
    [_packs removeObject:pack];
}
@end




@implementation BBPackFunc
@synthesize tgt, func;
-(void)dealloc{
    self.tgt = nil;
    [super dealloc];
}

+(id)action:(id)tgt func:(SEL)func{
    BBPackFunc* pack = [[[[self class] alloc] init] autorelease];
    pack.tgt = tgt;
    pack.func = func;
    return pack;
}
-(void)doAction{
    [self retain];
    [self.tgt performSelector:self.func];
    [self callbackMethod];
    [self release];
}

@end


@implementation BBPackFuncD
@synthesize param;
-(void)dealloc{
    //NSLog(@"BBPackFuncD:dealloc");
    self.param = nil;
    [super dealloc];
}

+(id)action:(id)tgt func:(SEL)func param:(id)param{
    BBPackFuncD* pack = [[[[self class] alloc] init] autorelease];
    pack.tgt = tgt;
    pack.func = func;
    pack.param = param;
    return pack;
}
-(void)doAction{
    [self retain];
    [self.tgt performSelector:self.func withObject:self.param];
    [self callbackMethod];
    [self release];
}

@end

@implementation BBPackFuncDD
@synthesize param2;
-(void)dealloc{
    self.param2 = nil;
    [super dealloc];
}
+(id)action:(id)tgt func:(SEL)func param:(id)param param2:(id)param2{
    BBPackFuncDD* pack = [[[[self class] alloc] init] autorelease];
    pack.tgt = tgt;
    pack.func = func;
    pack.param = param;
    pack.param2 = param2;
    return pack;
}
-(void)doAction{
    [self retain];
    [self.tgt performSelector:self.func withObject:self.param withObject:self.param2];
    [self callbackMethod];
    [self release];
}
@end



@implementation BBPackFuncDL
-(void)doActionWithData:(id)data{
    [self retain];
    [self.tgt performSelector:self.func withObject:data];
    [self callbackMethod];
    [self release];
}

@end



